import React, { useContext, useState } from "react";
import getConfig from "next/config";
import Link from "next/link";
import jwt from "jsonwebtoken";
import moment from "moment";
import styled, { keyframes, css } from "styled-components";
import { Pin } from "@styled-icons/boxicons-regular/Pin";
import { Plus } from "@styled-icons/boxicons-regular/Plus";
import { Search } from "@styled-icons/boxicons-regular/Search";
import { Filter } from "@styled-icons/boxicons-regular/Filter";
import SEO from "../../components/SEO";
import Box from "../../components/Box";
import Text from "../../components/Text";
import { withAuthServerSideProps } from "../../utils/withAuth";
import Button from "../../components/Button";
import Input from "../../components/Input";
import LocaleContext from "../../utils/LocaleContext";

// 动画效果
const fadeIn = keyframes`
  from {
    opacity: 0;
    transform: translateY(20px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
`;

const scaleIn = keyframes`
  from {
    transform: scale(0.95);
    opacity: 0;
  }
  to {
    transform: scale(1);
    opacity: 1;
  }
`;

const AnnouncementCard = styled(Box)`
  background: ${(props) => props.theme.colors.sidebar};
  border-radius: 12px;
  min-height: 100px;
  padding: 24px 32px 20px 20px;
  margin-bottom: 20px;
  transition: box-shadow 0.2s, transform 0.2s;
  cursor: pointer;
  position: relative;
  display: flex;
  flex-direction: column;
  justify-content: center;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.04);
  overflow: visible;
  border: none;
  &:hover {
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
    transform: translateY(-2px);
  }
  &::before {
    content: "";
    position: absolute;
    top: 18px;
    left: 0;
    width: 5px;
    height: calc(100% - 36px);
    border-radius: 4px;
    background: ${(props) =>
      props.pinned
        ? props.theme.colors.primary
        : props.theme.colors.primary + "33"};
    opacity: 0.9;
  }
`;

const PinBadge = styled(Box)`
  position: absolute;
  top: 18px;
  right: 24px;
  padding: 4px 14px;
  border-radius: 16px;
  font-size: 0.9rem;
  font-weight: 500;
  background: ${(props) => props.theme.colors.primary};
  color: #fff;
  display: flex;
  align-items: center;
  gap: 6px;
  z-index: 2;
`;

const SearchBar = styled(Box)`
  position: relative;
  margin-bottom: 32px;
  max-width: 520px;

  input {
    padding-left: 44px;
    border-radius: 12px;
    height: 46px;
    font-size: 1rem;
    border: 2px solid ${(props) => props.theme.colors.border};
    background: ${(props) => props.theme.colors.background};
    transition: all 0.3s;
    box-shadow: none;

    &:focus {
      border-color: ${(props) => props.theme.colors.primary};
      box-shadow: 0 0 0 2px ${(props) => props.theme.colors.primary}22;
      background: #fff;
    }
  }
`;

const SearchIcon = styled(Search)`
  position: absolute;
  left: 16px;
  top: 50%;
  transform: translateY(-50%);
  color: ${(props) => props.theme.colors.grey};
  width: 22px;
  height: 22px;
`;

const FilterButton = styled(Button)`
  position: relative;
  padding: 12px 24px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;

  &:hover {
    transform: translateY(-1px);
  }
`;

const CreateButton = styled(Button)`
  padding: 12px 24px;
  border-radius: 12px;
  display: flex;
  align-items: center;
  gap: 8px;
  transition: all 0.3s ease;

  &:hover {
    transform: translateY(-1px);
  }
`;

const AnnTitle = styled(Text)`
  font-size: 1.25rem;
  font-weight: bold;
  margin-bottom: 8px;
  margin-left: 12px;
  color: ${(props) => props.theme.colors.text};
  word-break: break-all;
`;

const AnnMeta = styled(Box)`
  display: flex;
  align-items: center;
  gap: 18px;
  margin-left: 12px;
  color: ${(props) => props.theme.colors.grey};
  font-size: 0.95rem;
`;

const Announcements = ({
  announcements = [],
  pinnedAnnouncements = [],
  userRole,
}) => {
  const { getLocaleString } = useContext(LocaleContext);
  const [searchQuery, setSearchQuery] = useState("");
  const [filter, setFilter] = useState("all"); // all, pinned, unpinned

  const allAnnouncements = [...pinnedAnnouncements, ...announcements];

  const filteredAnnouncements = allAnnouncements.filter((announcement) => {
    const matchesSearch = announcement.title
      .toLowerCase()
      .includes(searchQuery.toLowerCase());
    const matchesFilter =
      filter === "all" ||
      (filter === "pinned" && announcement.pinned) ||
      (filter === "unpinned" && !announcement.pinned);
    return matchesSearch && matchesFilter;
  });

  return (
    <>
      <SEO title={getLocaleString("navAnnouncements")} />

      <Box
        mb={6}
        css={css`
          animation: ${fadeIn} 0.5s ease forwards;
        `}
      >
        <Box
          display="flex"
          alignItems="center"
          justifyContent="space-between"
          mb={4}
        >
          <Text as="h1" fontSize={4} fontWeight="bold">
            {getLocaleString("navAnnouncements")}
          </Text>

          <Box display="flex" gap={3}>
            <FilterButton variant="secondary">
              <Filter size={20} />
              {getLocaleString("filter")}
            </FilterButton>

            {userRole === "admin" && (
              <Link href="/announcements/new" passHref>
                <CreateButton as="a">
                  <Plus size={20} />
                  {getLocaleString("reqCreateNew")}
                </CreateButton>
              </Link>
            )}
          </Box>
        </Box>

        <SearchBar>
          <SearchIcon />
          <Input
            placeholder={getLocaleString("searchAnnouncements")}
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
            width="100%"
          />
        </SearchBar>

        <Box>
          {filteredAnnouncements.map((announcement) => (
            <Link
              key={announcement._id}
              href={`/announcements/${announcement.slug}`}
              passHref
            >
              <AnnouncementCard as="a" pinned={announcement.pinned}>
                {announcement.pinned && (
                  <PinBadge>
                    <Pin size={16} />
                    {getLocaleString("annPinned")}
                  </PinBadge>
                )}
                <AnnTitle>{announcement.title}</AnnTitle>
                <AnnMeta>
                  <Text>
                    {getLocaleString("reqPostedBy")}:{" "}
                    {announcement.createdBy?.username ?? "deleted user"}
                  </Text>
                  <Text>•</Text>
                  <Text>
                    {moment(announcement.created).format(
                      `${getLocaleString("indexTime")}`
                    )}
                  </Text>
                </AnnMeta>
              </AnnouncementCard>
            </Link>
          ))}
        </Box>
      </Box>
    </>
  );
};

export const getServerSideProps = withAuthServerSideProps(
  async ({ token, fetchHeaders }) => {
    if (!token) return { props: {} };

    const {
      publicRuntimeConfig: { SQ_API_URL },
      serverRuntimeConfig: { SQ_JWT_SECRET },
    } = getConfig();

    const { role } = jwt.verify(token, SQ_JWT_SECRET);

    try {
      const announcementsRes = await fetch(
        `${SQ_API_URL}/announcements/page/0`,
        {
          headers: fetchHeaders,
        }
      );
      if (
        announcementsRes.status === 403 &&
        (await announcementsRes.text()) === "User is banned"
      ) {
        throw "banned";
      }
      const announcements = await announcementsRes.json();

      const pinnedAnnouncementsRes = await fetch(
        `${SQ_API_URL}/announcements/pinned`,
        {
          headers: fetchHeaders,
        }
      );
      const pinnedAnnouncements = await pinnedAnnouncementsRes.json();

      return {
        props: { announcements, pinnedAnnouncements, userRole: role || "user" },
      };
    } catch (e) {
      if (e === "banned") throw "banned";
      return { props: {} };
    }
  }
);

export default Announcements;
